Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] web3 versioned transaction support #27213

Closed
wants to merge 5 commits into from

Conversation

jstarry
Copy link
Member

@jstarry jstarry commented Aug 17, 2022

This draft PR will be broken up into smaller PRs but gives a look at what all the versioned transaction classes and APIs look like together

Classes

Naming suggestions welcomed

TransactionMessage

This class should be used to:
- construct new transactions (legacy or v0)
- display not-yet-processed transactions (in wallets)
- display already-processed transactions (in explorers)
- convert compiled messages (legacy or v0) into a more usable form

VersionedTransaction

This class should be used to:
- sign compiled (legacy or v0) messages (by wallets)
- serialize into a wire transaction buffer
- deserialize a wire transaction buffer

MessageV0

This class should be used to:
- serialize into a v0 message buffer for signing
- deserialize a v0 message buffer

MessageAccountKeys

This class won't be used directly by developers but is used internally to wrap static account keys and dynamic account keys loaded from lookup tables

CompiledKeys

This class won't be used directly by developers but is used internally to extract account keys that can be loaded from an address lookup table

@jstarry jstarry added the noCI Suppress CI on this Pull Request label Aug 17, 2022
});
const transaction = new VersionedTransaction(
new MessageV0({
header: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So using the new compilation to build this transaction would work like this?

const transaction = new VersionedTransaction(
    MessageV0.compile({
        payerKey: payer.publicKey,
        instructions: [transferIx],
        recentBlockhash: blockhash,
        addressLookupTableAccounts: [lookupTableAccount],
    })
);

Sounds good to me.

Maybe this test could send a second transaction that was compiled that way? Possibly add a handful of testcases where the MessageV0.compile() output is compared to an expected result?

@jstarry
Copy link
Member Author

jstarry commented Aug 18, 2022

Here's a rough guide for how these new classes would be used:

  1. App builds transaction for user
const txMessage = new TransactionMessage({
  instructions,
  recentBlockhash,
  payerKey,
});

// if desired, legacy transactions can still be used
const versionedTx = new VersionedTransaction(
  txMessage.compile({version: 'legacy'}),
);

// if lookup tables are needed, v0 is required
const versionedTx = new VersionedTransaction(
  txMessage.compile({
    version: 0,
    addressLookupTableAccounts,
  });
);

// send via wallet for signing
const wallet = WalletAdapter.useWallet();
wallet.sendTransaction(versionedTx, connection);
  1. Transaction is received by wallet
const addressLookupTableAccounts = await Promise.all(
  versionedTx.message.addressTableLookups.map((lookup) => {
    return connection.getAddressLookupTable(lookup.tableKey);
  });
);

// Decompile the transaction message to display details to the user
const txMessage = TransactionMessage.decompile({
  message: versionedTx.message,
  addressLookupTableAccounts,
});

// Simulate the transaction (not yet implemented)
await connection.simulateTransaction(versionedTx);

// Sign the transaction
versionedTx.sign([walletKeypair]);

// Send the transaction
await connection.sendRawTransaction(versionedTx);
  1. Transaction is fetched by explorer
// Fetch versioned transaction
const transactionResponse = await connection.getTransaction(signature, {
  maxSupportedTransactionVersion: 0,
});

// Decompile the transaction message to display details to the user
const txMessage = TransactionMessage.decompile({
  message: transactionResponse.transaction.message,
  loadedAddresses: transactionResponse.meta.loadedAddresses,
});

@jstarry jstarry force-pushed the web3/decompile-message branch 2 times, most recently from 9f8df2c to d2252c1 Compare August 18, 2022 22:51
@jstarry jstarry force-pushed the web3/decompile-message branch from d2252c1 to 5b326b0 Compare August 26, 2022 09:33
@codecov
Copy link

codecov bot commented Aug 26, 2022

Codecov Report

Merging #27213 (5b326b0) into master (e779032) will decrease coverage by 4.1%.
The diff coverage is n/a.

❗ Current head 5b326b0 differs from pull request most recent head 72c6339. Consider uploading reports for the commit 72c6339 to get more accurate results

@@            Coverage Diff            @@
##           master   #27213     +/-   ##
=========================================
- Coverage    76.9%    72.8%   -4.2%     
=========================================
  Files          48       54      +6     
  Lines        2505     2835    +330     
  Branches      355      387     +32     
=========================================
+ Hits         1927     2064    +137     
- Misses        448      638    +190     
- Partials      130      133      +3     

@jstarry jstarry force-pushed the web3/decompile-message branch from 5b326b0 to 72c6339 Compare September 1, 2022 00:06
@jstarry jstarry closed this Sep 1, 2022
@mergify
Copy link
Contributor

mergify bot commented Sep 1, 2022

⚠️ The sha of the head commit of this PR conflicts with #27526. Mergify cannot evaluate rules on this PR. ⚠️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
noCI Suppress CI on this Pull Request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants